/****************************************************************************
*
* Description: Base exception
* Module: 'functional.h'
* Created at: 03.12.06 09:43:08 UTC
*
* $Revision$
*
****************************************************************************/
#pragma once

#if !defined(__COMMON_FUNCTIONAL_H__)
#define __COMMON_FUNCTIONAL_H__

#include <string>
#include <ostream>
#include <algorithm>

namespace common {

/* Functional object for algorithms that can use it on containers items.  */
template < class T >
class output_item_to_stream
{
public:
	output_item_to_stream (std::ostream & str, const char * postfix) :
		str_(&str), postfix_(postfix)
	{}

	output_item_to_stream (std::ostream & str, std::string & postfix) :
		str_(&str), postfix_(postfix)
	{}

	void operator () (T & val)
	{
		*str_ << val << postfix_;
	}

private:
	std::ostream * str_;
	std::string postfix_;
};

/* Output container to stream.  */
template < class T >
class output_container_to_stream
{
public:
	output_container_to_stream (std::ostream & str, const char * postfix) :
		str_(&str), postfix_(postfix)
	{}

	std::ostream & operator () (T & val)
	{
		std::for_each(
		  val.begin(),
		  val.end(),
		  output_item_to_stream<T::value_type>(*str_, postfix_));
		return *str_;
	}

private:
	std::ostream * str_;
	std::string postfix_;
};

/* Functional object for algorithms that can use it on maps items.  */
template < class T >
class output_map_item_to_stream
{
public:
	output_map_item_to_stream (std::ostream & str, const char * postfix) :
		str_(&str), postfix_(postfix)
	{}

	output_map_item_to_stream (std::ostream & str, std::string & postfix) :
		str_(&str), postfix_(postfix)
	{}

	void operator () (T & val)
	{
		*str_ << "[" << val.first << "]" << postfix_;
	}

private:
	std::ostream * str_;
	std::string postfix_;
};

/* Output map to stream.  */
template < class T >
class output_map_to_stream
{
public:
	output_map_to_stream (std::ostream & str, const char * postfix) :
		str_(&str), postfix_(postfix)
	{}

	std::ostream & operator () (T & val)
	{
		std::for_each(
		  val.begin(),
		  val.end(),
		  output_map_item_to_stream<T::value_type>(*str_, postfix_));
		return *str_;
	}

private:
	std::ostream * str_;
	std::string postfix_;
};

} /* End of common.  */

#endif /* End of __COMMON_FUNCTIONAL_H__.  */